#include "Rp2WglRenderer.h"

using namespace Rp2;

//---------------------------------------------------------------------------------------------------
WglRenderer::WglRenderer(HWND hWnd, int iWinWidth, int iWinHeight)
	:
	OpenGLRenderer(iWinWidth, iWinHeight)
{
	m_hWnd = hWnd;
	m_hDC = GetDC(m_hWnd);

	SetupRC();

	// Initialize glew.
	glewInit();	

	InitializeState();

}
//---------------------------------------------------------------------------------------------------
WglRenderer::~WglRenderer()
{
	if (m_hGLrc)
	{
		wglDeleteContext(m_hGLrc);
	}

	if (m_hDC)
	{
        ReleaseDC(m_hWnd, m_hDC);
	}
}
//---------------------------------------------------------------------------------------------------
bool WglRenderer::SetupRC()
{

	// set pixel format and glrc. 
	PIXELFORMATDESCRIPTOR pfd;
	int PixelFormat;

	if (m_hDC == NULL)
	{	
		assert(false);
		MessageBox(m_hWnd, TC("Error: Can't Get Device Context for Window"), TC("ERROR"), MB_OK | MB_ICONERROR);
		return (false);							
	}

	memset (&pfd, 0, sizeof(pfd));
	pfd.nSize		= sizeof(PIXELFORMATDESCRIPTOR);
	pfd.nVersion	= 1;
	pfd.dwFlags		= PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
	pfd.cColorBits	= 24;
	pfd.cDepthBits	= 32;

	PixelFormat = ChoosePixelFormat(m_hDC, &pfd);
	if (PixelFormat == 0)
	{	
		MessageBox(m_hWnd, TC("Error: Can't Choose Pixel Format"), TC("ERROR"), MB_OK | MB_ICONERROR);
		ReleaseDC (m_hWnd, m_hDC);
		m_hDC = NULL;
		return (false);							
	}

	if (SetPixelFormat(m_hDC, PixelFormat, &pfd) == 0)	
	{
		MessageBox(m_hWnd, TC("Error: Can't Set The Pixel Format"), TC("ERROR"), MB_OK | MB_ICONERROR);
		ReleaseDC (m_hWnd, m_hDC);
		m_hDC = NULL;
		return (false);								
	}

	m_hGLrc = wglCreateContext(m_hDC);

	if (m_hGLrc == NULL)
	{
		MessageBox(m_hWnd, TC("Error: Can't Create GL Context"), TC("ERROR"), MB_OK | MB_ICONERROR);
		ReleaseDC (m_hWnd, m_hDC);
		m_hDC = NULL;
		return (false);								
	}

	if (!wglMakeCurrent(m_hDC, m_hGLrc))					
	{
		MessageBox(m_hWnd, TC("Error: Can't Make Current GL Context"), TC("ERROR"), MB_OK | MB_ICONERROR);
		wglDeleteContext(m_hGLrc);
		ReleaseDC (m_hWnd, m_hDC);
		m_hGLrc	= NULL;
		m_hDC	= NULL;
		return (false);								
	}	


    // Get the number of supported texture images for vertex program.
    ms_iMaxVShaderImages = 0;
    glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,&ms_iMaxVShaderImages);


    // Get the number of supported texture units for pixel programs.
    ms_iMaxPShaderImages = 0;
    glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,&ms_iMaxPShaderImages);
    if (ms_iMaxPShaderImages > 0)
    {
        m_apkActiveSamplers =
            new SamplerInformation*[ms_iMaxPShaderImages];

        memset(m_apkActiveSamplers,0,ms_iMaxPShaderImages*
            sizeof(SamplerInformation*));
    }

    ms_iMaxTCoords = 0;
    glGetIntegerv(GL_MAX_TEXTURE_COORDS,&ms_iMaxTCoords);


    // OpenGL supports a primary and a secondary color
    ms_iMaxColors = 2;

    // Set up light model.  TO DO:  The GL light function calls here are
    // not necessary for a shader-based engine.
    GLint iMaxLights;
    glGetIntegerv(GL_MAX_LIGHTS,&iMaxLights);
    assert(iMaxLights > 0);
    ms_iMaxLights = (int)iMaxLights;
    m_aspkLight = new ObjectPtr[ms_iMaxLights];
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,(const float*)ColorRGBA::BLACK);
    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_FALSE);
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE);
    glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR);
    glDisable(GL_LIGHTING);

    // Get the stencil buffer size.
    GLint iBits = 0;
    glGetIntegerv(GL_STENCIL_BITS,&iBits);
    ms_iMaxStencilIndices = (iBits > 0 ? (1 << iBits) : 0);

    // Get the maximum number of user-defined clip planes.
    GLint iMaxUseClipPlanes = 0;
    glGetIntegerv(GL_MAX_CLIP_PLANES,&iMaxUseClipPlanes);
    ms_iMaxUserClipPlanes = (int)iMaxUseClipPlanes;	

    // Get the maximum anisotropic distortion.  The default is 1.0f.
    glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,&ms_fMaxAnisotropy);

    // Disable drawing of lines as sequences of dashes.
    glDisable(GL_LINE_STIPPLE);

	return true;
}
//---------------------------------------------------------------------------------------------------